package com.dingding.special.order.appoint.biz.taxi;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.dingding.common.core.beans.UserTaxiOrdert;
import com.dingding.common.core.beans.Userdetail;
import com.dingding.common.core.push.enums.push.SpecialDriverPushEnum;
import com.dingding.common.core.push.factory.dtos.OrderDurationDTO;
import com.dingding.common.core.push.factory.request.IPushRequestFactory;
import com.dingding.common.core.util.amap.AmapApi;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.special.order.appoint.biz.IAppointOrderService;
import com.dingding.special.order.appoint.cache.AppointOrderCache;
import com.dingding.special.order.appoint.dao.IAppointDao;
import com.dingding.special.order.grab.service.IUserGrabService;
import com.dingding.special.user.customer.dao.ICustomerUserDao;
import com.dingding.special.user.driver.dao.IDriverUserDao;
import com.dingding.special.user.driver.dto.onlinedriver.OLineDriverDto;

/**
 * @Description 指派实时的出租车订单
 * @author fengshuonan
 * @date 2016年11月22日 上午10:35:10
 */
@Component("appointRealTaxiOrderService")
public class AppointRealTaxiOrderServiceImpl implements IAppointOrderService {

	private Logger log = Logger.getLogger(this.getClass());

	@Resource(name = "driverUserDao")
	private IDriverUserDao driverUserDao;

	@Resource(name = "customerUserDao")
	private ICustomerUserDao customerUserDao;

	@Resource(name = "specialDriverPushRequestFactory")
	private IPushRequestFactory specialDriverPushRequestFactory;

	@Resource(name = "customerPushRequest")
	private IPushRequestFactory customerPushRequest;

	@Resource(name = "queueFacade")
	private IQueueFacade queueFacade;

	@Resource(name = "appointDao")
	private IAppointDao appointDao;

	@Resource(name = "userGrabService")
	private IUserGrabService userGrabService;

	@Override
	public boolean appointOrder(Object userorder) {
		
		log.error("----------------- 指派订单开始 -----------------");

		// 指派的订单类型为UserTaxiOrdert
		UserTaxiOrdert userTaxiOrdert = (UserTaxiOrdert) userorder;

		// 如果该订单不存在或者不是待指派状态，则返回成功，不让队列里继续存在
		if (this.appointDao.getTaxiOrderStatus(userTaxiOrdert.getTaxiOrdertId()) != 1) {
			log.error("订单不存在或者订单状态不是待指派状态！");
			log.error("----------------- 指派订单结束 -----------------");
			AppointOrderCache.deleteRedisOrder(userTaxiOrdert);
			return true;
		}

		// 获取所有的在线的出租车司机
		List<OLineDriverDto> allOnlineTaxiDrivers = this.driverUserDao
				.getAllOnlineTaxiDrivers(userTaxiOrdert.getPlaceOrderCity());
		
		log.error("获取所有的在线出租车司机，在线出租车司机人数为：" + allOnlineTaxiDrivers.size());

		// 遍历一下出租车司机的集合，如果有匹配的司机，则给这个司机推送订单
		for (OLineDriverDto dto : allOnlineTaxiDrivers) {
			boolean flag = this.isMacthing(userorder, dto);
			
			//如果订单与司机的条件相匹配，则推送给司机这个单
			if(flag == true){
				
				/**
				 * 判断司机近期30秒之内有没有被指派过订单
				 * 如果被指派过,则略过此人
				 */
				if(AppointOrderCache.haveAppointedRecently(dto.getUserId(),userTaxiOrdert.getTaxiOrdertId())){
					continue;
				}
				
				//获取乘客的详情
				Userdetail userdetail = this.customerUserDao.getUserdetail(userTaxiOrdert.getPlaceOrderUserId());
				
				// 乘客与司机不能是同一个人(防止刷单)
				if(dto.getTelPhone().equals(userdetail.getTellphone())){
					continue;
				}
				
				//获取订单的里程信息
				OrderDurationDTO orderDurationDTO = this.appointDao.getTaxiOrderDuration(dto,userTaxiOrdert);
				
				//推送给司机订单
				pushDriverOrder(userTaxiOrdert, dto, userdetail, orderDurationDTO);
				log.error("推送订单" + userTaxiOrdert.getTaxiOrdertId() + "给司机:" + dto.getUserId());
			}
		}
		log.error("----------------- 指派订单结束 -----------------");
		return false;
	}

	/**
	 * @Description 发送指派订单的推送给司机
	 * @param userspecialorderT 专车订单临时表中的订单
	 * @param dto 在线司机的详细信息封装
	 * @param userdetail 乘客的用户详情
	 * @param orderDurationDTO 订单历程信息的封装
	 * @author fengshuonan
	 */
	protected void pushDriverOrder(UserTaxiOrdert userTaxiOrdert, OLineDriverDto dto, Userdetail userdetail,
			OrderDurationDTO orderDurationDTO) {
		//推送订单给司机
		String pushBean = this.specialDriverPushRequestFactory.createPushRequestString(SpecialDriverPushEnum.AppointTaxiOrderPush.toString(),
				dto.getUserId(),userdetail, userTaxiOrdert,orderDurationDTO);
		this.queueFacade.addPushToQueue(pushBean);
	}

	@Override
	public boolean isMacthing(Object userorder, OLineDriverDto oLineDriverDto) {

		// 指派的订单类型为UserTaxiOrdert
		UserTaxiOrdert userTaxiOrdert = (UserTaxiOrdert) userorder;

		// 判断是否司机有出租车订单
		boolean flag = this.appointDao.isDriverHaveTaxiOrder(oLineDriverDto.getUserId());

		// 如果有进行中订单，则不给司机匹配这个单
		if (flag == true) {
			log.error("司机有出租车订单！该司机不匹配，司机id为：" + oLineDriverDto.getUserId());
			return false;
		}

		// 获取订单出发地的经纬度，还有司机当前的经纬度
		double startLng = userTaxiOrdert.getStartLongitude();
		double startlat = userTaxiOrdert.getStartLatitude();
		double driverLng = oLineDriverDto.getLongitude();
		double driverlat = oLineDriverDto.getLatitude();

		// 计算两点的距离
		BigDecimal distance = new BigDecimal(0);
		try {
			distance = AmapApi.getTwoPointDistance(startLng, startlat, driverLng, driverlat);
		} catch (Exception e) {
			log.error("获取两点之间的距离出错！AppointRealOrderServiceImpl : isMacthing()", e);
			return false;
		}

		// 如果乘客和司机距离小于司机的偏好距离
		if (distance.compareTo(oLineDriverDto.getDistanceFilter()) <= 0) {
			log.error("乘客和司机的距离小于司机的偏好距离！该订单与该司机匹配!");
			return true;
		} else {
			log.error("偏好距离不匹配！" + oLineDriverDto.getUserId());
			return false;
		}
	}
}